home *** CD-ROM | disk | FTP | other *** search
/ 3D Images / 3D Images.iso / programs / amiga / wasp / src.lha / src / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-22  |  7.8 KB  |  418 lines

  1. /* wasp - Copyright 1991 by Steven Reiz
  2.  * see COPYING and wasp.c for further info
  3.  * io.c, 30/5/91 - 2/6/91, 8/7/91, 8/12/91,
  4.  * 27/12/91 - 1/1/92, 21/3/92
  5.  */
  6.  
  7. /* all Wasp I/O should go through the functions which are defined
  8.  * in this file, copen_in/out, cseek_in/out, cread, cwrite and wrl
  9.  * for handling the input- and outputimagefiles,
  10.  * cout_tmp, cout_default and ctmp_move for working with temporary
  11.  * output files,
  12.  * printe and pute for messages that cannot be handled by errorx,
  13.  * init_counter, counter and erase_counter for producing a counter,
  14.  * errorx (not called directly, use error0, error1, etc.) for error-
  15.  * messages.
  16.  */
  17.  
  18. static char *sourcefile=__FILE__;
  19.  
  20. #include "wasp.h"
  21.  
  22. #ifdef AMIGA
  23. #define TMP_PREFIX "t:"
  24. #else
  25. #define TMP_PREFIX "/tmp/"
  26. #endif
  27.  
  28. extern int errno;
  29.  
  30. /* to make it possible to read the start of the input file multiple
  31.  * times (so each reader can try to recognize it), even when reading
  32.  * from stdin, the first MAXINBUF bytes are stored in a buffer, inbuf.
  33.  */
  34. #define MAXINBUF 256
  35. static char *inbuf;
  36. static int inbufn;        /* actual number of bytes in inbuf */
  37. static long infdpos, incpos;    /* the real and virtual positions of infd */
  38. static long outfdpos, outcpos;  /* and outfd */
  39.  
  40. /* temporary file stuff */
  41. static int ran_nr;        /* for tmp files, to not clash with other wasps */
  42. static long tmp_ctr=0;
  43. static int tmpfd= -1;
  44. static char tmpfilename[30];
  45.  
  46.  
  47. void
  48. copen_in(char *filename)
  49. {
  50.     srand(time(NULL));
  51.     ran_nr=rand();
  52.  
  53.     if (!strcmp(filename, "-"))
  54.         infd=0;
  55.     else if ((infd=open(filename, O_RDONLY))<0)
  56.         error1(E0_FATAL, E1_IO, E2_OPEN, E3_ERRNO, filename);
  57.     outcpos=0;
  58.     inbuf=Malloc(MAXINBUF);
  59.     inbufn=read(infd, inbuf, MAXINBUF);
  60.     if (inbufn<0)
  61.         error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, filename);
  62.     else if (!inbufn)
  63.         error1(E0_FATAL, E1_IO, E2_READ, E3_UNEXPEND, infilename);
  64.     infdpos=inbufn;
  65. }
  66.  
  67.  
  68. void
  69. copen_out(char *filename)
  70. {
  71.     if (!strcmp(filename, "-"))
  72.         outfd=1;
  73.     else if ((outfd=open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644))<0)
  74.         error1(E0_FATAL, E1_IO, E2_CREAT, E3_ERRNO, filename);
  75.     outfdpos=0;
  76.     outcpos=0;
  77. }
  78.  
  79.  
  80. long
  81. cseek_in(long offset, int whence)
  82. {
  83.     if (whence==0)
  84.         incpos=offset;
  85.     else if (whence==1)
  86.         incpos+=offset;
  87.     else
  88.         assert(0);
  89.     assert(incpos>=0);
  90.     if (incpos!=infdpos && incpos>=inbufn) {
  91.         if (infd>2) {
  92.             if (lseek(infd, incpos, 0)<0)
  93.                 error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, infilename);
  94.             infdpos=incpos;
  95.         } else if (incpos>infdpos) {
  96.             char *m;
  97.             int n;
  98.  
  99.             n=incpos-infdpos;
  100.             m=Malloc(n);
  101.             if (read(infd, m, n)!=n)
  102.                 error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, infilename);
  103.             free(m);
  104.             infdpos=incpos;
  105.         } else
  106.             error0(E0_FATAL, E1_IO, E2_SEEK, E3_SEEK_STDIN);
  107.     }
  108.     return incpos;
  109. }
  110.  
  111.  
  112. long
  113. cseek_out(long offset, int whence)
  114. {
  115.     assert(tmpfd== -1);
  116.     if (whence==0)
  117.         outcpos=offset;
  118.     else if (whence==1)
  119.         outcpos+=offset;
  120.     else {
  121.         assert(!offset);
  122.         if ((outfdpos=lseek(outfd, 0L, 2))<0)
  123.             error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, outfilename);
  124.         outcpos=outfdpos;
  125.     }
  126.     assert(outcpos>=0);
  127.     if (outcpos!=outfdpos) {
  128.         if (outfd>2) {
  129.             if (lseek(outfd, outcpos, 0)<0)
  130.                 error1(E0_FATAL, E1_IO, E2_SEEK, E3_ERRNO, outfilename);
  131.             outfdpos=outcpos;
  132.         } else
  133.             error0(E0_FATAL, E1_IO, E2_SEEK, E3_SEEK_STDOUT);
  134.     }
  135.     return outcpos;
  136. }
  137.  
  138.  
  139. int
  140. read1(void *buf, int len)
  141. {
  142.     int todo, rr;
  143.  
  144.     todo=len;
  145.     if (incpos<inbufn) {
  146.         int min;
  147.  
  148.         min=inbufn-incpos;
  149.         if (min>todo)
  150.             min=todo;
  151.         memcpy(buf, inbuf+incpos, min);
  152.         todo-=min;
  153.         incpos+=min;
  154.         if (!todo)
  155.             return min;
  156.     }
  157.     assert(incpos==infdpos);
  158.     rr=read(infd, (char *)buf+(len-todo), todo);
  159.     if (rr<0) {
  160.         if (todo!=len)
  161.             return len-todo;
  162.         return rr;
  163.     }
  164.     infdpos+=rr;
  165.     incpos+=rr;
  166.     todo-=rr;
  167.     return len-todo;
  168. }
  169.  
  170.  
  171. /* cread_type       er     eof    varlen  misc
  172.  * CREAD_STRICT     fatal  fatal  fatal   default
  173.  * CREAD_NONFATAL   error  error  error
  174.  * CREAD_VARLEN     error  error
  175.  * CREAD_OPTIONAL   error
  176.  */
  177. void
  178. cread(void *buf, int len)
  179. {
  180.     assert(cread_type>=CREAD_STRICT && cread_type<=CREAD_OPTIONAL);
  181.     if ((cread_result=read1(buf, len))!=len) {
  182.         if (cread_result<0) {
  183.             if (cread_type==CREAD_STRICT)
  184.                 error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, infilename);
  185.             else
  186.                 error1(E0_ERROR, E1_IO, E2_READ, E3_ERRNO, infilename);
  187.         } else if (cread_type==CREAD_STRICT)
  188.             error1(E0_FATAL, E1_IO, E2_READ, E3_UNEXPEND, infilename);
  189.         else if (cread_type==CREAD_NONFATAL
  190.          || (cread_type==CREAD_VARLEN && !cread_result))
  191.             error1(E0_ERROR, E1_IO, E2_READ, E3_UNEXPEND, infilename);
  192.     }
  193. }
  194.  
  195.  
  196. void
  197. cwrite(void *buf, int len)
  198. {
  199.     if (tmpfd== -1) {
  200.         assert(outcpos==outfdpos);
  201.         if (write(outfd, buf, len)!=len)
  202.             error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, outfilename);
  203.         outfdpos+=len;
  204.         outcpos+=len;
  205.     } else {
  206.         if (write(tmpfd, buf, len)!=len)
  207.             error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, tmpfilename);
  208.     }
  209. }
  210.  
  211.  
  212. void
  213. wrl(unsigned long l)
  214. {
  215.     cwrite(&l, 4);    /* BYTEORDER */
  216. }
  217.  
  218.  
  219. void
  220. wrs(unsigned short s)
  221. {
  222.     cwrite(&s, 2);    /* BYTEORDER */
  223. }
  224.  
  225.  
  226. void
  227. cout_tmp(void)
  228. {
  229.     assert(tmpfd== -1);
  230.     sprintf(tmpfilename, "%swasp.%04d.%03ld", TMP_PREFIX, ran_nr%10000,
  231.      tmp_ctr%1000L);
  232.     if ((tmpfd=open(tmpfilename, O_WRONLY|O_CREAT|O_TRUNC, 0644))<0)
  233.         error1(E0_FATAL, E1_IO, E2_CREAT, E3_ERRNO, tmpfilename);
  234. }
  235.  
  236.  
  237. void
  238. cout_default(long *tmp_num, long *tmp_size)
  239. {
  240.     assert(tmpfd!= -1);
  241.     *tmp_size=lseek(tmpfd, 0L, 1);
  242.     *tmp_num=tmp_ctr++;
  243.     close(tmpfd);
  244.     tmpfd= -1;
  245. }
  246.  
  247.  
  248. void
  249. ctmp_move(long tmp_num)
  250. {
  251.     int fd, n;
  252.     char *buf;
  253. #define CTMP_BUF 16384
  254.     long len=0;
  255.  
  256.     assert(tmp_ctr>tmp_num && tmpfd== -1);
  257.     buf=Malloc(CTMP_BUF);
  258.     sprintf(tmpfilename, "%swasp.%04d.%03ld", TMP_PREFIX, ran_nr%10000,
  259.      tmp_num%1000L);
  260.     if ((fd=open(tmpfilename, O_RDONLY))<0)
  261.         error1(E0_FATAL, E1_IO, E2_OPEN, E3_ERRNO, tmpfilename);
  262.     assert(outcpos==outfdpos);
  263.     while ((n=read(fd, buf, CTMP_BUF))>0) {
  264.         if (write(outfd, buf, n)!=n)
  265.             error1(E0_FATAL, E1_IO, E2_WRITE, E3_ERRNO, outfilename);
  266.         len+=n;
  267.     }
  268.     if (n<0)
  269.         error1(E0_FATAL, E1_IO, E2_READ, E3_ERRNO, tmpfilename);
  270.     outfdpos+=len;
  271.     outcpos+=len;
  272.     close(fd);
  273.     unlink(tmpfilename);
  274.     free(buf);
  275. }
  276.  
  277.  
  278. int
  279. printe(char *s, ...)
  280. {
  281.     va_list argp;
  282.     int res;
  283.  
  284.     va_start(argp, s);
  285.     res=vfprintf(stderr, s, argp);
  286.     va_end(argp);
  287.     return res;
  288. }
  289.  
  290.  
  291. void
  292. pute(char c)
  293. {
  294.     putc(c, stderr);
  295. }
  296.  
  297.  
  298. static int co, cur, step, dir=0, len, last1;
  299.  
  300. void
  301. init_counter(int start, int end, int instep, char *s, ...)
  302. {
  303.     va_list argp;
  304.  
  305.     va_start(argp, s);
  306.     if (start<=end)
  307.         dir=1;
  308.     else
  309.         dir= -1;
  310.     step=instep;
  311.     if (step<0)
  312.         step= -step;
  313.     cur=start;
  314.     co=1;
  315.     last1=end;
  316.     len=printe("\r       [%d..%d] ", start, end)-1;
  317.     if (s)
  318.         len+=vfprintf(stderr, s, argp);
  319.     pute('\r');
  320.     fflush(stderr);
  321.     va_end(argp);
  322. }
  323.  
  324.  
  325. void
  326. counter(void)
  327. {
  328.     if (--co && (co!=1 || ((dir<0 && cur-step>last1) || (dir>=0 && cur+step<last1))))
  329.         return;
  330.     printe("\r%6d", cur);
  331.     co=step;
  332.     if (dir<0)
  333.         cur-=step;
  334.     else
  335.         cur+=step;
  336.     fflush(stderr);
  337. }
  338.  
  339.  
  340. void
  341. erase_counter(char *s, ...)
  342. {
  343.     va_list argp;
  344.     int l1;
  345.  
  346.     va_start(argp, s);
  347.     pute('\r');
  348.     if (s)
  349.         l1=vfprintf(stderr, s, argp);
  350.     else
  351.         l1=0;
  352.     while (l1++ <len)
  353.         pute(' ');
  354.     pute(s ? '\n' : '\r');
  355.     fflush(stderr);
  356.     dir=0;
  357.     va_end(argp);
  358. }
  359.  
  360.  
  361. void
  362. prin1(char *p)
  363. {
  364.     if (p)
  365.         printe("%s ", p);
  366. }
  367.  
  368.  
  369. void
  370. errorx(long code, ...)
  371. {
  372.     va_list argp;
  373.     char c0, c1, c2, c3;
  374.     char *p;
  375.     int l1;
  376.  
  377.     va_start(argp, code);
  378.     if (dir) {
  379.         pute('\r');
  380.         l1=0;
  381.         while (l1++ <len)
  382.             pute(' ');
  383.         pute('\r');
  384.         fflush(stderr);
  385.     }
  386.     c0=code>>24;
  387.     c1=code>>16;
  388.     c2=code>>8;
  389.     c3=code;
  390.     if (c0==E0_INTERNAL) {
  391.         printe("internal error in wasp %s, file %s, line %ld; please report to sreiz@cs.vu.nl\n",
  392.          version+14, va_arg(argp, char *), code&0x00ffffff);
  393.         exit(1);
  394.     }
  395.     assert(c0>E0_INTERNAL && c0<E0_NUM && c1>0 && c1<E1_NUM && c2>0
  396.      && c2<E2_NUM && c3>0 && c3<E3_NUM);
  397.     prin1(e0_s[c0].s1);
  398.     prin1(e1_s[c1]);
  399.     prin1(e2_s[c2]);
  400.     p=e0_s[c0].s2;
  401.     if (p)
  402.         printe("%s", p);
  403.     if (c3==E3_ERRNO) {
  404.         printe(" in ");
  405.         perror(va_arg(argp, char *));
  406.     } else {
  407.         p=e3_s[c3];
  408.         if (p) {
  409.             printe(": ");
  410.             vfprintf(stderr, p, argp);
  411.         }
  412.         pute('\n');
  413.     }
  414.     if (c0==E0_FATAL)
  415.         exit(1);
  416.     va_end(argp);
  417. }
  418.